﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Model
{
    /// <summary>
    /// 类转换，把包含类成员的类型S转换成基本成员的类型T
    /// </summary>
    public class ClassConvert<T,S> where T : new()
    {
        private static readonly List<PropertyInfo> _propertyOfT = typeof(T).GetProperties().ToList();
        private static List<PropertyInfo> PropertyOfT
        {
            get { return _propertyOfT; }
        }


        /// <summary>
        /// 把对象S中包含的基本属性和类成员属性值提取出来赋值给T中对应的属性
        /// </summary>
        /// <returns></returns>
        public static T Convert(S source)
        {
            var itemResult = new T();
            ExtractPropertyValue(typeof(S), source, itemResult);
            return itemResult;
        }
        /// <summary>
        /// 把列表S中包含的基本属性和类成员属性值提取出来赋值给T中对应的属性
        /// </summary>
        /// <returns></returns>
        public static IList<T> Convert(List<S> source)
        {
            List<T> resultList = new List<T>();
           
            foreach (S itemSource in source)
            {
                var itemResult = new T();
                ExtractPropertyValue(typeof (S), itemSource, itemResult);
                resultList.Add(itemResult);
            }
            return resultList;
        }

        /// <summary>
        /// 从类型S中提取属性，把对应的属性赋值给targetValue，S的类成员不能有属性跟S本身的属性相同
        /// </summary>
        /// <param name="type">要处理的类型，可能是S，也可能是S的成员的类型</param>
        /// <param name="sourceValue">S对象</param>
        /// <param name="targetValue">T对象</param>
        private static void ExtractPropertyValue(Type type, object sourceValue, T targetValue)
        {
            foreach (var property in type.GetProperties())
            {
                if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string)) //C#基本类型
                {
                    var propertyT = PropertyOfT.Find(item => item.Name == property.Name);
                    if (propertyT == null) continue;//T中没有对应的属性，不处理
                    propertyT.SetValue(targetValue, property.GetValue(sourceValue));
                    //if (propertyT.Name == "Id" && propertyT.GetValue(targetValue).ToString() != "0") return;//防止类成员和类本身都有Id属性
                }
                else//非C#基本类型
                {
                    if (property.GetValue(sourceValue) == null) return;//子对象值为null，不处理
                    ExtractPropertyValue(property.PropertyType, property.GetValue(sourceValue), targetValue);
                }
            }
        }
       
    }
}
